import { hcNamespace } from "./constant";
import { isArray, isString } from "./types";

export const addClass = (el: HTMLElement, cls: string) => el.classList.add(cls);
export const removeClass = (el: HTMLElement, cls: string) => el.classList.remove(cls);

export const find = (el: HTMLElement | string, query: string): HTMLElement => {
  if (isString(el)) {
    return document.querySelector(el as string);
  }

  return (el as HTMLElement).querySelector(query);
}

export const queryCss = (el: HTMLElement, style: string) => window.getComputedStyle(el, null).getPropertyValue(style);

export const setCss = (el: HTMLElement, style: string, value: string | number) => el.style[style] = value;

export const css = (el: HTMLElement, style: string, value?: string | number) => {
  if (value === undefined) {
    return queryCss(el, style);
  }

  return setCss(el, style, value);
}

export const hide = (el: HTMLElement) => css(el, "display", "none");

export const show = (el: HTMLElement) => css(el, "display", "");

export const on = (el: HTMLElement, type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions) => {
  if (!isArray(el[nsKey(type)])) {
    el[nsKey(type)] = [];
  }

  listener[nsKey(type)] = options;
  el[nsKey(type)].push(listener);
  return el.addEventListener(type, listener, options);
}

export const off = (el: HTMLElement, type: string, listener?: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions) => {
  const listeners = el[nsKey(type)];
  if (listener === undefined && isArray(listeners)) {
    listeners.forEach((listener) => {
      off(el, type, listener, listener[nsKey(type)]);
    })
  }
  
  if (isArray(listeners)) {
    const index = listeners.indexOf(listener);
    if (index > 0) {
      listeners.splice(index, 1);
    }
  }

  el.removeEventListener(type, listener, options);
}

export const attr = (el: HTMLElement, qualifiedName: string, value: string) => {
  if (value === undefined) {
    return el.getAttribute(qualifiedName);
  }

  return el.setAttribute(qualifiedName, value);
}

export const text = (el: HTMLElement, text?: string) => {
  if (text === undefined) {
    return el.innerText;
  }

  el.innerText = text;
}

function nsKey(k) {
  return `${hcNamespace}_${k}`;
}